// ProjectName: go-learn-demo
// PackageName: redisybxb
// Description:
// Author: hy.bai
// Date: 2025-08-31, 星期日 19:40

package redisybxb

import (
	"fmt"
	"github.com/redis/go-redis/v9"
	"log/slog"
)

// 开启一个事务
func RedisTxPipeline() {
	client, ctx, err := InitClient()
	if err != nil {
		slog.Error(fmt.Sprintf("Redis Init Error: %s", err.Error()))
	}

	// Redis的事务和关系型数据的事务是有区别的：
	// 关系型数据库的事务：多个SQL语句，要么全部成功，要么全部失败。
	// Redis的事务：只能确保多个Redis命令单线程一起执行，但是执行多个命令中间如果出现错误，不会自动回滚，需要业务开发通过写代码进行主动回滚。
	// 1.开启一个事务
	pipeline := client.TxPipeline()
	// 2.执⾏多个Redis命令
	pipeline.Get(*ctx, "name-txp1")
	pipeline.Set(*ctx, "name-txp2", "txp-value", 0)
	// 3.使用Exec方法提交事务
	cmder, errExec := pipeline.Exec(*ctx)
	if errExec != nil {
		// 发生错误，放弃事务，通过写代码进行主动回滚。
		// 即：如果发生错误，可以在这里使用代码进行主动回滚。
		slog.Error(fmt.Sprintf("Redis Exec Error: %s", errExec.Error()))
		return
	}
	fmt.Println("事务提交成功")
	// 循环结果
	for ind := range cmder {
		cmd := cmder[ind]
		// 强制转换成对应的数据类型
		statusCmd := cmd.(*redis.StatusCmd)
		fmt.Println(statusCmd.Val())
	}
}

// 因为不会自动回滚，所以不推荐使用Redis的事务。

func TestTxPipeline() {
	RedisTxPipeline()
}
